package com.xxl.job.admin.core.alarm;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xxl.job.admin.core.model.*;
import com.xxl.job.admin.core.scheduler.XxlJobScheduler;
import com.xxl.job.admin.core.util.TenantContextUtil;
import com.xxl.job.admin.dao.XxlJobAlarmConfigDao;
import com.xxl.job.admin.dao.XxlJobAlarmRecordDao;
import com.xxl.job.admin.dao.XxlJobLogDetailDao;
import com.xxl.job.core.biz.ExecutorBiz;
import com.xxl.job.core.biz.model.LogParam;
import com.xxl.job.core.biz.model.LogResult;
import com.xxl.job.core.biz.model.ReturnT;
import jakarta.annotation.Resource;

/**
 * @author xuxueli 2020-01-19
 */
public abstract class JobAlarm {

    @Resource
    private XxlJobAlarmRecordDao xxlJobAlarmRecordDao;

    @Resource
    private XxlJobAlarmConfigDao xxlJobAlarmConfigDao;

    @Resource
    private XxlJobLogDetailDao xxlJobLogDetailDao;

    /**
     * @param alarmType 通知类型 1、钉钉  2、企业微信 3 飞书 4、邮件
     * @return
     */
    public XxlJobAlarmConfig getConfig(Integer alarmType) {
        LambdaQueryWrapper<XxlJobAlarmConfig> queryWrapper = Wrappers.lambdaQuery(XxlJobAlarmConfig.class)
                .eq(XxlJobAlarmConfig::getValidStatus, "Y")
                .eq(XxlJobAlarmConfig::getAlarmType, alarmType);
        return xxlJobAlarmConfigDao.selectOne(queryWrapper);
    }

    /***
     * 预警前，记录日志
     * @param info
     * @param jobLog
     */
    public Long beforeAlarm(XxlJobInfo info, XxlJobLog jobLog, Integer alarmType) {
        TenantContextUtil.setTenantId(info.getTenantId());
        XxlJobAlarmConfig config = getConfig(alarmType);
        if (config != null) {
            XxlJobAlarmRecord record = new XxlJobAlarmRecord();
            record.setLogId(jobLog.getId());
            record.setJobId(info.getId());
            record.setJobGroupId(info.getJobGroup());
            record.setAlarmType(alarmType);
            record.setAlarmConfigId(config.getId());
            record.setAlarmStatus(0);
            //判断是否抑制
            if (config.getAlarmInterval() > 0) {
                XxlJobAlarmRecord latestSuccessSend = xxlJobAlarmRecordDao.getLatestSuccessSend(alarmType);
                if (latestSuccessSend != null
                        && latestSuccessSend.getCreateDate().getTime() + config.getAlarmInterval() * 60 * 1000 > System.currentTimeMillis()) {
                    record.setAlarmStatus(1);
                }
            }
            int insertCount = xxlJobAlarmRecordDao.insert(record);
            if (insertCount < 1) {
                return null;
            }
            if (record.getAlarmStatus() == 1) {
                return null;
            }
            return record.getId();

        }
        return null;

    }

    /***
     * 预警后，更新日志
     * @param recordId
     * @param alarmStatus  0:推送中；1：推送抑制；2：推送成功；3：推送失败
     * @param errorMsg
     */
    public void afterAlarm(Long recordId, Integer alarmStatus, String errorMsg) {
        XxlJobAlarmRecord record = xxlJobAlarmRecordDao.selectById(recordId);
        record.setAlarmStatus(alarmStatus);
        record.setErrorMsg(StrUtil.sub(errorMsg, 0, 3000));
        xxlJobAlarmRecordDao.updateById(record);
    }

    /***
     * 获取jobLog详情
     * @param jobLog
     * @return
     */
    public String getJobLogDetail(XxlJobLog jobLog) {
        try {
            XxlJobLogDetail logDetail = xxlJobLogDetailDao.selectById(jobLog.getId());
            if (logDetail == null) {
                ExecutorBiz executorBiz = XxlJobScheduler.getExecutorBiz(jobLog.getExecutorAddress());
                ReturnT<LogResult> logResult = executorBiz.log(new LogParam(jobLog.getTriggerTime().getTime(), jobLog.getId(), 1));
                return logResult.getContent().getLogContent();
            } else {
                return logDetail.getLogDetail();
            }
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * job alarm
     *
     * @param info
     * @param jobLog
     * @return
     */
    public abstract void doAlarm(XxlJobInfo info, XxlJobLog jobLog);

}
